/*--------------------------------------------
File Name:    zealdollar.js
Depend On:    ----
Created Date: 2007-11-28 00:00 By Rex.Sun
Last Updated: 2008-06-16 12:06 By Rex.Sun
--------------------------------------------*/
var $window = this;
var $undef = function(o, p){ return (typeof (o || $window)[p] == "undefined"); };
var $oUdf = function(o){ return typeof o == "undefined"; };
var $oUim = function(o){ throw new Error("Unimplemented!"); };
var $oNul = function(o){ return o === null; };
var $oArr = function(o){ return o instanceof Array; };
var $oFun = function(o){ return typeof o == "function"; };
var $oBol = function(o){ return typeof o == "boolean" || o instanceof Boolean; };
var $oNum = function(o){ typeof o == "number" || o instanceof Number; };
var $oStr = function(o){ return typeof o == "string" || o instanceof String; };
var $oVal = function(o){ return ($oStr(o) || $oNum(o) || $oBol(o) || $oNul(o)); };
var $oObj = function(o){ return !$oVal(o); };
var $V = function(o){ return $oVal(o) ? o : o.valueOf(); };
var $A = function(arr){
    if (!arr) return [];
    if ($oArr(arr)) return arr;
    if ($oVal(arr)){
        var rar = [];
        rar.push(arr);
        return rar;
    }
    var l = arr.length, rtval = new Array(l);
    while (l--) rtval[l] = arr[l];
    return rtval;
};
var $E = function(msg, ctx){
    var ex = Error(msg);
    $setto(ex, {context : ctx});
    throw ex;
};
var $ = function (elm){
    if (arguments.length > 1) {
        for (var i = 0, elms = [], l = arguments.length; i < l; i++){
            elms.push($(arguments[i]));
        }
        return elms;
    }
    if ($oStr(elm)){
        elm = document.getElementById(elm);
    }
    return elm;
};
var $seton = function(obj, ps){
    if (!obj) obj = {};
    if (!ps) return;
    for (var p in ps){
        if (!obj[p]){
            obj[p] = ps[p];
        }
    }
    return obj;
};
var $setto = function(obj, ps){
    if (!obj) obj = {};
    if (!ps) return;
    for (var p in ps){
        obj[p] = ps[p];
    }
    return obj;
};
var $try = function(){
    var rtval = null;
    for (var i = 0, l = arguments.length; i < l; i++){
        var f = arguments[i];
        try{
            rtval = $exes(f);
            break;
        }catch(ex){}
    }
    return rtval;
};
var $gat = function(obj, nam, create){
    if(!obj || !nam) return undefined;
    if(!$undef(obj, nam)) return obj[nam];
    return (!!create ? (obj[nam]={}) : undefined);
};
var $get = function(){
    if(!arguments) return undefined;
    var obj = arguments[0];
    for(var i=1, l=arguments.length; i<l; i++){
        var nam = arguments[i];
        obj = $gat(obj, nam);
        if(!obj) break;
    }
    return obj;
};
var $clone = function(obj){
	if (obj instanceof Object){
		var v = {};
		for (var k in obj){
			v[k] = obj[k];
		}
		return v;
	}
	return obj;
};
var $watch = function(obj, onm){
    var s = ["{"];
    for (var k in obj){
        s.push(k);
        if (!onm){
            s.push(":");
            try{
                var val = null;
                if ($oVal(obj[k])){
                    val = String($V(obj[k]) || "_N/A_").wrap('"');
                }else if ($oFun(obj[k])){
                    val = "function(){}";
                }else{
                    val = $watch(obj[k], onm);
                }
            }catch(ex){
                val = '"_E/R_"';
            }
            s.push(val);
        }
        s.push(", ");
    }
    s.pop();
    s.push("}");
    return s.join("");
};
var $exes = function(f, args){
    if (!f || !$oFun(f)){ return undefined; }
    return f.apply(f, $A(args));
};
var $exea = function(f, args, cb, cbargs){
    var af = function(){
        $exes(f, args);
        $exes(cb, cbargs);        
    };
    setTimeout(af, 1);
    af = null;
};
var $dispose = function(obj){
    if (obj){
        $exes(obj.dispose);
        obj = null;    
    }
    return null;
};
//==== String ====
$seton(String.prototype,{
trim: function(){
    return this.replace(/^\s*(\S*(\s+\S+)*)\s*$/,"$1");
},
collapse: function(){
    return this.replace(/\s+/g,' ').trim();    
},
wrap: function(delim)
{
    var close, delims = {"(":")", "{":"}", "[":"]", "<":">", "</":">"};
    if (delims[delim]){
        close = delims[delim];
    }
    else{
        var m = (/^<(\w+)(\s+\w+\s*=\s*"[^"]*")*\s*>$/).exec(delim);
        if (m){
            close = "</" + m[1] + ">";
        }
    }
    return delim + this + (close ? close : delim);
},
padLeft: function(n, c){
    var s = this;
    var x = n - s.length;
    if (x > 0){
        c = c || " ";
        s = (new Array(Math.ceil(x / c.length) + 1)).join(c) + s;
        return s.substring(s.length - n, n);
    }
    return s;
},
padRight: function (n, c){
    s = this;
    var x = n - s.length;
    if (x > 0){
        c = c || " ";
        s = s + (new Array(Math.ceil(x / c.length))).join(c);
        return s.substring(0, n);
    }
    return s;
},
format: function(){
    var fmt = this;
    for(var i=0, l=arguments.length; i < l; i++){
        fmt = fmt.replace( new RegExp('\\{' + i + '\\}',"mg"), arguments[i] );
    }
    return fmt;
},
equals: function(str2, ignoreCase){
    var str1 = this;
    if (str1 == null && str2 == null){
        return true;
    } else if (str1 == null || str2 == null){
        return false;
    }
    if (ignoreCase){
        return str1.toLowerCase() == str2.toLowerCase();
    }
    else{
        return str1 == str2;
    }
},
encodeHtml: function(){
    var rtval = this.replace(/\>/g, "&gt;").replace(/\</g, "&lt;").replace(/\&/g, "&amp;").replace(/\'/g, "&#039;").replace(/\"/g, "&quot;");
    return rtval;
},
hasXss: function(){
    var xssRe = /<|&lt|\\u0*3c|\\x0*3c|%3C|&#0*60|>|&gt|\\u0*3e|\\x0*3e|%3E|&#0*62/gi;
    return xssRe.test(this);
},
escape: function(){
    return !!(encodeURIComponent) ? encodeURIComponent(this) : escape(this);
},
unescape: function(){
    return !!(decodeURIComponent) ? decodeURIComponent(this) : unescape(this);
}});
//==== Array ====
$seton(Array.prototype,{
foreach: function(proc) {
    for (var i = 0, l = this.length; i < l; i++){
        proc(this[i]);
    }
},
push: function(){
    for (var i = 0, l = arguments.length; i < l; i++){
        this[this.length] = arguments[i];
    }
    return this.length;
},
pop: function(){
    if (this.length > 0){
        return this[--this.length];
    }else{
        return null;
    }
},
indexOf: function(elm, bgnIdx){
    bgnIdx = bgnIdx || 0;
    if (bgnIdx < 0) bgnIdx = 0;
    for (var i = 0, l = this.length; i < l; i++){
        if (this[i] === elm){
            return i;
        }
    }
    return -1;
},
contains: function(elm){
    return (this.indexOf(elm) >= 0);
},
shift: function(){
    return this.splice(0,1)[0];
},
last: function(){
    return (this.length > 0 ? this[this.length-1] : void(0));
},
remove: function(obj){
    for(var i=this.length-1; i>=0; i--){
        if ( this[i] === obj ){
            this.splice(i, 1);
        }
    }
    return this;
},
map: function(fun, context){
    var ret = [];
    for(var i=0, l=this.length; i < l; i++){
        ret.push(fun.call(context, this[i], i, this));
    }
    return ret;
},
splice: function(idx, num){
    var delta;
    var addCount = arguments.length - 2;
    if(idx > this.length){
        idx = this.length;
    }
    if(idx + num > this.length){
        num = this.length - idx;
    }
    var deleted = [];
    for(var i = 0; i < num; ++i){
        deleted.push(this[idx+i]);
    }
    if(addCount > num){
        delta = addCount - num;
        for(i = this.length + delta - 1; i>=idx+delta; i--){
            this[i] = this[i - delta];
        }
    }
    else if (addCount < num){
        delta = num - addCount;
        for(i = idx + addCount; i < this.length-delta; i++){
            this[i] = this[i + delta];
        }
        for(; i < this.length - 1; ++i){
            delete this[i];
        }
        this.length -= delta;
    }
    for(i = 0; i < addCount; ++i ){
        this[idx+i] = arguments[2+i];
    }
    return deleted;
}});
//==== Date ====
$seton(Date.prototype,{
toXmlString: function(hasMs){
    return "{0}-{1}-{2} {3}:{4}:{5},{6}".format(this.getFullYear(), String(this.getMonth() + 1).padLeft(2, '0'), String(this.getDate()).padLeft(2, '0'), String(this.getHours()).padLeft(2, '0'), String(this.getMinutes()).padLeft(2, '0'), String(this.getSeconds()).padLeft(2, '0'), (hasMs ? String(this.getMilliseconds()).padLeft(3, '0') : ""));
},
toUTCXmlString: function(hasMs){ //2000-01-01T00:00:00Z000
    return "{0}-{1}-{2}T{3}:{4}:{5}Z{6}".format(this.getUTCFullYear(), String(this.getUTCMonth() + 1).padLeft(2, '0'), String(this.getUTCDate()).padLeft(2, '0'), String(this.getUTCHours()).padLeft(2, '0'), String(this.getUTCMinutes()).padLeft(2, '0'), String(this.getUTCSeconds()).padLeft(2, '0'), (hasMs ? String(this.getUTCMilliseconds()).padLeft(3, '0') : ""));
},
toNumString: function(hasMs){ //20000101000000000
    return "{0}{1}{2}{3}{4}{5}{6}".format(this.getUTCFullYear(), String(this.getUTCMonth() + 1).padLeft(2, '0'), String(this.getUTCDate()).padLeft(2, '0'), String(this.getUTCHours()).padLeft(2, '0'), String(this.getUTCMinutes()).padLeft(2, '0'), String(this.getUTCSeconds()).padLeft(2, '0'), (hasMs ? String(this.getUTCMilliseconds()).padLeft(3, '0') : ""));
}});
//==== $T ====
$setto(this,{
$T: function(cb, inMs, atOnce, isOnce){
    var m_this = this;
    var m_cb = cb;
    var m_ms = inMs;
    var m_timerId = 0;
    var m_running = false;
    var m_atOnce = parseBool(atOnce, false);
    var m_isOnce = parseBool(isOnce, false);
    var m_handler = function(){
        if (m_running){
            m_invoke();
            if (m_isOnce){
                m_this.stop();
                return;
            }
            m_timerId = setTimeout(m_handler, m_ms);
        }
    };
    var m_invoke = function(){
        $exes(m_cb);
    };
    this.setPeriod = function(inMs){
        m_ms = inMs;
    };
    this.start = function(){
        m_running = true;
        if (m_atOnce){
            m_invoke();
            if (m_isOnce){
                m_this.stop();
                return;
            }
        }
        m_timerId = setTimeout(m_handler, m_ms);
    };    
    this.stop = function(){
        m_running = false;
        if (m_timerId > 0){
            clearTimeout(m_timerId);
            m_timerId = 0;
        }
    };    
}});
//==== Uri helper ====
$setto(this,{$U:{
xdomainProxy: "",
fixPath: function(uri, isPath){
    var rtval = String(uri);
    if (rtval){
        if(isPath && rtval.lastIndexOf("/") < rtval.length - 1){
            rtval += "/";
        }
        if(!isPath){
            while(rtval.lastIndexOf("/") == rtval.length - 1){ rtval = rtval.substring(0,rtval.length - 1) }
        }
    }
    return rtval;
},
fixDomain: function(uri){
    var rtval = String(uri);
    var regAb = new RegExp("https*://","i");
    var regMy = new RegExp("://" + this.hostname + "(:\d+)*/","i");
    if (regAb.test(rtval) && !regMy.test(rtval) && this.xdomainProxy){
        rtval = this.xdomainProxy + rtval.escape();
    }
    return rtval;
},
getParam: function(url, pname){
    var rtval = "";
    url = url || location.href;
    url = String(url).replace(/(#[^#]*)+/g,'').slice(url.indexOf('?')+1);
    var params = url.split('&');
    for (var i=0, l=params.length; i < l; i++){
        var ps = String(params[i]).split('=');
        var pn = $get(ps, "0");
        var pv = $get(ps, "1");
        if (pn.equals(pname, true)){
            rtval = String(pv).unescape();
            break;
        }
    }
    return rtval;
},
setParam: function(url, pname, val){
    var rtval = "";
    url = url || location.href;
    if (url){
        url = String(url);
        var ov = this.getParam(url, pname);
        var pv = "{0}={1}".format(pname,String(val).escape());
        if (ov!=""){
            rtval = url.replace(new RegExp("[?]{0}={1}".format(pname, ov), "ig"), "?"+pv);
            rtval = rtval.replace(new RegExp("&{0}={1}".format(pname, ov), "ig"), "&"+pv);
        }else{
            url = url.replace(/#+/, "{0}#");
            if (url.indexOf("{0}")<0){
                url += "{0}";
            }
            rtval = url.format(((url.indexOf("?")>=0)?"&":"?") + pv);
        }        
    }
    return rtval;
},
getCookie: function(name){
	var rtval = "";
    var ck = document.cookie;
	var s = ck.indexOf(name+"=");
	var len = s + name.length + 1;
	if (s >= 0 && name.equals(ck.substring(0, name.length), true)){
	    var e = ck.indexOf(";",len);
	    if (e == -1) e = ck.length;
	    rtval = ck.substring(len,e);
	}
	return rtval.unescape();
},
setCookie: function(name,value,expmins,path,domain,secure){
	var expString = null;
	if (expmins)
	{
		var d = new Date();
		d.setMinutes(d.getMinutes()+expmins);
		expString = d.toGMTString();
	}
	var rtval = [];
	rtval.push("{0}={1}".format(name,value.escape()));
	if (expString) {rtval.push(";expires=" + expString)};
	if (path) {rtval.push(";path=" + path)};
	if (domain) {rtval.push(";domain=" + domain)};
	if (secure) {rtval.push(";secure")};
	document.cookie = rtval.join("");
}}});
//==== $ajax : ajax request pool ====
$setto(this,{
ajaxMaster: function(){
    var m_id = -1;
    var m_this = this;
    var m_timer = null;
    var m_pool = new Array();    
    var m_checkTimeouts = function(){
        if (m_pool.length > 0){
            var now = new Date();            
            for (var i = 0; i < m_pool.length; i++){
                var item = m_pool[i];                
                if (item && item.Timeout){
                    var dt = new Date(item.BeginTime);
                    dt.setUTCMilliseconds(item.Timeout);
                    if (dt < now){
                        item.Overtimed = true;
                        m_this.cancelItem(item.Id);
                    }
                }
            }
        }
    };
    var m_removeItem = function(aId){
        if (aId >= m_pool.length){ return; }
        var aItem = m_pool[aId];
        m_pool[aId] = null;
        $dispose(aItem);
    };
    var m_requestComplete = function(aItem){
        if (!aItem){ return; }
        var httpObj = aItem.HttpObj;
        if (httpObj.readyState == 4){
            var s = httpObj.status;
            if ((!s)||((200 <= s)&&(300 > s))||(aItem.Allow304 && (s==304))){
                $exes(aItem.CBFunc, [httpObj.responseText, aItem.CBData]);
            }
            m_removeItem(aItem.Id);            
        }
    };
    this.getSycText = function(url, allow304){
        var rtval = "";
        var cb = function(txt){ rtval = txt; };
        var rt = m_this.request(url, true, cb, false, allow304);
        rtval = rtval || rt;
        return rtval;
    };
    this.getResp = function(url, cb, isasy, allow304, cbData, timeout){
        return m_this.request(url, true, cb, isasy, allow304, cbData, null, timeout);
    };
    this.postResp = function(url, cb, isasy, allow304, cbData, postData, timeout){
        return m_this.request(url, false, cb, isasy, allow304, cbData, postData, timeout);
    };
    this.request = function(url, isGet, cb, isasy, allow304, cbData, postData, timeout){
        var method = isGet ? "GET" : "POST";
        var httpObj = $try(
            function(){ return new ActiveXObject('MSXML2.XMLHTTP.6.0');},
            function(){ return new ActiveXObject('MSXML2.XMLHTTP.5.0');},
            function(){ return new ActiveXObject('MSXML2.XMLHTTP.4.0');},
            function(){ return new ActiveXObject('MSXML2.XMLHTTP.3.0');},
            function(){ return new ActiveXObject('MSXML2.XMLHTTP');},
            function(){ return new ActiveXObject('Microsoft.XMLHTTP');},
            function(){ return new XMLHttpRequest();}
        );
        if(httpObj){
            var aItem = new ajaxItem(++m_id, httpObj, !!allow304, cb, cbData, timeout);
            m_pool[m_id] = aItem;
            if (timeout && !m_timer){
                m_timer = new $T(m_checkTimeouts, 1000, false, false);
                m_timer.start();
            }
            httpObj.onreadystatechange = function(){
                m_requestComplete(aItem); 
            };
            url = $U.fixDomain(url);
            httpObj.open(method, url, !!isasy);            
            if (isGet) {
                httpObj.send(null);
            } else {
                httpObj.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
                httpObj.send(postData);
            }
            return httpObj.responseText;
        }
        else{
            $E("XMLHTTP is not available!");
        }
    };
    this.getItem = function(aId){
        var aItem = null;
        if (aId < m_pool.length){
            aItem = m_pool[aId];
        }
        return aItem;
    };
    this.cancelItem = function(aId){
        var aItem = m_this.getItem(aId);
        if (aItem && (aItem.httpObj.readyState != 4)){
            aItem.httpObj.abort();
        }        
        m_removeItem(aId);
    };    
},
ajaxItem: function(id, httpObj, allow304, cb, cbData, timeout){
    this.Id = id;
    this.CBFunc = cb;
    this.CBData = cbData;
    this.HttpObj = httpObj;
    this.Timeout = timeout;
    this.Overtimed = false;
    this.Allow304 = allow304;
    this.BeginTime = new Date();
    this.dispose = function(){
        this.Id = null;
        this.CBFunc = null;
        this.CBData = null;
        this.Timeout = null;
        this.HttpObj = null;
        this.BeginTime = null;
    };
}});
$setto(this,{$ajax:new ajaxMaster()});
//==== Namespace ====
$setto(this,{$N:{
defaultNsUri: "",
libPackFile: "__ns__.js",
hostname: location.hostname.toLowerCase(),
addRootPath: function(ns, path, update){
    if (!ns || !path){ return; }
    var nsRoot = ns.split(".")[0];
    if (!this.libRootPath[nsRoot] || update){
        this.libRootPath[nsRoot] = $U.fixPath($U.fixPath(this.defaultNsUri, true) + path, true);
    }
},
getJsPath: function(ns){
    var rtval = ns;
    if (!/\/+/.test(ns))
    {
        var nms = ns.split(".");
        var len = nms.length;
        if (len > 0){
            if (this.libRootPath[nms[0]]){
                var lr = this.libRootPath[nms[0]];
                nms[0] = $U.fixPath(lr, false);
            }
            else{
                nms[0] = this.libRootPath["sys"] + nms[0];
            }
            if (nms[len-1] != "*"){
                nms[len-1] += ".js";
            }
            else{
                nms[len-1] = this.libPackFile;
            }
            rtval = nms.join("/");
        }
    }
    return rtval;
}}});
$setto(this,{
$import: function(jsuri, refresh){
    if (!jsuri){ return; }
    var parsepath = (refresh && jsuri.indexOf("?")<0);
    if (refresh) { jsuri = $U.setParam(jsuri,"refresh",new Date().toNumString(true)); }
    var jsrpath = (parsepath ? jsuri.split("?")[0] : jsuri);
    var ok = $N.loadedPackagesUri[jsrpath];
    if (!ok){
        var jsc = $ajax.getSycText(jsuri, true);
        if (jsc){
            ok = $N.loadedPackagesUri[jsrpath] = true;
            return jsc;
        }
    }
    return ok;    
},
$using: function(ns, nspath){
    if(!ns){ return; }
    $N.addRootPath(ns, nspath, !!nspath);
    var jsuri = $N.getJsPath(ns);
    var rtval = $import(jsuri, true);
    return rtval;
},
$initCore: function(xProxy, defaultNs){
    $setto($U,{xdomainProxy: xProxy});
    $setto($N,{
        defaultNsUri: $U.fixPath(defaultNs, true),
        libRootPath: { sys : $U.fixPath(defaultNs + "js_p_sys", true) },
        loadedPackagesUri: { "zealdollar.js" : true }
    });
}});
$initCore("","");